package config

import (
	"ExchangeApp/global"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/plugin/dbresolver"
	"log"
	"time"
)

// initDB 初始化数据库连接
// 功能：创建数据库连接、配置读写分离、设置连接池参数
func initDB() {
	// 获取主库连接字符串
	dsn := AppConfig.Database.Dsn

	// 创建数据库连接
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
		// 不生成外键约束，避免迁移时的复杂依赖问题
		DisableForeignKeyConstraintWhenMigrating: true,
	})

	// 错误处理：数据库连接失败时终止程序
	if err != nil {
		log.Fatalf("Failed to initialize database, got error %v", err)
	}

	// 配置读写分离（如果从库配置不为空）
	dsnSlave := AppConfig.Database.DsnSlave

	// 实现数据库读写分离，提升性能和扩展性
	if dsnSlave != "" {
		// 配置主库（写库）和从库（读库）数据源
		err = db.Use(dbresolver.Register(dbresolver.Config{
			// 写库（主库）数据源 - 用于所有写入操作
			Sources: []gorm.Dialector{mysql.Open(dsn)},
			// 读库（从库）数据源 - 用于所有读取操作
			Replicas: []gorm.Dialector{mysql.Open(dsnSlave)},
			// 负载均衡策略：随机选择读库 - 均衡分布读请求
			Policy: dbresolver.RandomPolicy{},
		}))

		// 检查读写分离配置是否成功
		if err != nil {
			log.Fatalf("配置 数据库读写分离 失败: %v", err)
		}
	}

	// 获取底层SQL数据库连接
	sqlDB, err := db.DB()

	// 设置数据库连接池参数
	// 最大空闲连接数
	sqlDB.SetMaxIdleConns(AppConfig.Database.MaxIdleConns)
	// 最大打开连接数
	sqlDB.SetMaxOpenConns(AppConfig.Database.MaxOpenConns)
	// 连接最大存活时间
	sqlDB.SetConnMaxLifetime(time.Hour)

	// 错误处理：连接池配置失败时终止程序
	if err != nil {
		log.Fatalf("Failed to configure database, got error: %v", err)
	}

	// 数据迁移（暂时注释掉）
	//err = db.AutoMigrate(
	//	&models.User{},
	//	&models.ExchangeRate{},
	//)
	//if err != nil {
	//	log.Fatalf("数据迁移失败 %v", err) // 记录迁移失败的错误日志
	//	return
	//}

	// 将数据库连接设置为全局变量，供其他模块使用
	global.Db = db
}
